﻿#include "VAOneXMLAdaptorSeaFacesDoubleCurve.h"
#include "rapidxml.hpp"
#include <QFile>
#include <iostream>
#include <QDebug>
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITKAcousticsPhysics/FITKAcousticsAbsNCT.h"
#include "FITKAcousticsModel/FITKAbstractSEASubSys.h"
#include "FITKAcousticsModel/FITKAbstractSEAFace.h"
#include "FITKAcousticsModel/FITKSEAFlatCurvedFace.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"
#include "FITK_Interface/FITKInterfaceModel/FITKElementFactory.h"

namespace IO
{

    QString VAOneXMLAdaptorSeaFacesDoubleCurve::getNodeName()
    {
        return "DoublyCurvedShellFace";
    }

    Acoustics::FITKAbstractSEASubSys::SEASubSysType VAOneXMLAdaptorSeaFacesDoubleCurve::getNodeType()
    {
        return Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell;
    }

    Acoustics::FITKAbstractSEAFace *VAOneXMLAdaptorSeaFacesDoubleCurve::createDataObjNode()
    {
        return new Acoustics::FITKSEADoublyCurvedFace;
    }

    void VAOneXMLAdaptorSeaFacesDoubleCurve::readRingNumber(rapidxml::xml_node<char> *node, Acoustics::FITKAbstractSEAFace *data)
    {
        if ((nullptr == data) || (nullptr == node))
        {
            return;
        }

        //双曲率面有ring参数
        bool bOk = true;
        int ringNum = readIntAttribute(node, "number_of_rings", &bOk);
        if (true != bOk)
        {
            qDebug()<<"ring number read error";
            return;
        }

        Acoustics::FITKSEADoublyCurvedFace *face = (Acoustics::FITKSEADoublyCurvedFace *)data;
        face->setNumberOfRing(ringNum);
    }

    void VAOneXMLAdaptorSeaFacesDoubleCurve::readTipNodeId(rapidxml::xml_node<char>* node, Acoustics::FITKAbstractSEAFace *data, QList<Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode> &list)
    {
        if ((nullptr == data) || (nullptr == node))
        {
            return;
        }

        //双曲率面有ring参数
        bool bOk = true;
        int tipNodeId = readIntAttribute(node, "tip_nodeid", &bOk);
        if (true != bOk)
        {
            qDebug()<<"tip node id read error";
            return;
        }

        Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode dataNode;
        dataNode._id = tipNodeId;
        dataNode._type = Acoustics::FITKAbstractSEASubSysWithNodes::Finish;
        list<<dataNode;
    }

    void VAOneXMLAdaptorSeaFacesDoubleCurve::readCell(rapidxml::xml_node<char> *node, Acoustics::FITKAbstractSEAFace *data)
    {
        if ((nullptr == node) || (nullptr == data))
        {
            return;
        }

        // <FlatPlateFace face_id="1">
        //         <NodeRef nodeid="13"/>
        //         <NodeRef nodeid="14"/>
        //         <Triangle node_id1="13" node_id2="154" node_id3="59"/>
        //         <Triangle node_id1="13" node_id2="154" node_id3="59"/>
        //         <PositiveFace trim_ref="Multiple NCT" trim_coverage="0.99"/>
        //         <NegativeFace trim_ref="2-layer treatment" trim_coverage="0.88"/>
        //</FlatPlateFace>

        // <SinglyCurvedFace face_id="7" face_name="" corner_index1="14" corner_index2="67" corner_index3="81">
        //         <NodeRef nodeid="13"/>
        //         <NodeRef nodeid="14"/>
        //         <Triangle node_id1="13" node_id2="154" node_id3="59"/>
        //         <Triangle node_id1="13" node_id2="154" node_id3="59"/>
        //         <PositiveFace trim_ref="Multiple NCT" trim_coverage="0.99"/>
        //         <NegativeFace trim_ref="2-layer treatment" trim_coverage="0.88"/>
        //</SinglyCurvedFace>

        // <DoublyCurvedShellFace face_id="15" face_name="" number_of_rings="1" tip_nodeid="16920" nodes_per_ring="198">
        //         <NodeRef nodeid="13"/>
        //         <NodeRef nodeid="14"/>
        //         <Triangle node_id1="13" node_id2="154" node_id3="59"/>
        //         <Triangle node_id1="13" node_id2="154" node_id3="59"/>
        //         <PositiveFace trim_ref="Multiple NCT" trim_coverage="0.99"/>
        //         <NegativeFace trim_ref="2-layer treatment" trim_coverage="0.88"/>
        //</DoublyCurvedShellFace>

        //读取face id
        readFaceId(node, data);

        //读取ring个数
        readRingNumber(node, data);

        //读取点信息
        QList<Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode> listNode = readNode(node);

        readTipNodeId(node, data, listNode);

        //起始节点类型设置
        if (2 <= listNode.size())
        {
            listNode.first()._type = Acoustics::FITKAbstractSEASubSysWithNodes::Start;
            listNode.last()._type = Acoustics::FITKAbstractSEASubSysWithNodes::Finish;
        }

        data->setNodes(listNode);

        //读取三角单元信息
        readTriangle(node, data);

        //噪声信息
        readNCT(node, data);
    }


    void VAOneXMLAdaptorSeaFacesDoubleCurve::writeRingTipInfo(Acoustics::FITKAbstractSEAFace *data, rapidxml::xml_node<char> *node)
    {
        if ((nullptr == data) || (nullptr == node)) return;

        //双曲率面有ring参数
        Acoustics::FITKSEADoublyCurvedFace *face = (Acoustics::FITKSEADoublyCurvedFace *)data;
        writeAttribute(node, "number_of_rings", face->getNumberOfRing());

        int num = 0;
        QList<Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode> listNode = data->getNodes();
        if (0 < face->getNumberOfRing()) num = (listNode.size() - 1) / face->getNumberOfRing();
 
        writeAttribute(node, "tip_nodeid", listNode.last()._id);
        writeAttribute(node, "nodes_per_ring", num);
        
    }

    void VAOneXMLAdaptorSeaFacesDoubleCurve::writeNode(Acoustics::FITKAbstractSEAFace *data, rapidxml::xml_node<char> *node)
    {
        if ((nullptr == data) || (nullptr == node))
        {
            return;
        }

        QList<Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode> listNode = data->getNodes();

        //写入点数据  最后一个节点写tip_node
        for (int i = 0; i < listNode.size() - 1; i++)
        {
            rapidxml::xml_node<char>* child = createNodeElement(node, "NodeRef");
            if (nullptr == child)
            {
                qDebug()<<"Face Node write failed";
                return;
            }

            writeAttribute(child, "nodeid", listNode[i]._id);
        }
    }

    void VAOneXMLAdaptorSeaFacesDoubleCurve::writeCell(Acoustics::FITKAbstractSEAFace *data, rapidxml::xml_node<char> *node)
    {
        if ((nullptr == data) || (nullptr == node))
        {
            return;
        }

        //使用objid作为face id
        writeFaceId(data, node);

        //写入ring 和tip信息
        writeRingTipInfo(data, node);

        //写入点数据
        writeNode(data, node);

        //写入三角单元
        writeTriangle(data, node);

        //噪声信息
        writeNCT(data, node);
    }
}
